export default class Service {
	#_data = {};
	#_origin = {};
	__dx__subscribe = {};
	constructor(ctx) {
		this.$dx = ctx;

		this.autoWrite = true;
		this.autoWriteTime = true;
		this.create_time = 'create_date';
		this.update_time = 'update_date';
		this.delete_time = 'delete_date';
		this.soft_delete = false;
		this.append = [];

		// 调用init
		if (typeof this.init === 'function') {
			//console.log('on service init：', this.constructor.name);
			this.init();
		}
	}
	//订阅
	$on(name, callback) {
		//console.log('on service 订阅：', name);
		if (typeof callback !== 'function') {
			throw new Error('缺少回调函数');
		}
		this.__dx__subscribe[name] = callback;
	}
	// 触发
	async $emit(name, ...args) {
		//console.log('on service 通知：', name);
		if (this.__dx__subscribe[name] === void 0) {
			return;
		}
		return await this.__dx__subscribe[name].apply(this, args);
	}
	//获取属性函数名称
	#getAttrName = function (str1) {
		let [str2, str3] = this.$dx.utils.caseTransform(str1);
		let str = '';
		if (typeof this[str1] == 'function') {
			str = str1;
		} else if (typeof this[str2] == 'function') {
			str = str2;
		} else if (typeof this[str3] == 'function') {
			str = str3;
		}
		return str;
	};

	// 设置器 设置数据
	async setAttr(name, value) {
		let str = this.#getAttrName('set_' + name + '_attr');
		if (str) {
			this.#_data[name] = await this[str](value);
		}
	}

	// 获取器 设置数据
	async getAttr(name, data = {}) {
		let str = this.#getAttrName('get_' + name + '_attr');
		if (typeof this[str] == 'function') {
			return await this[str](data[name], this.$dx.utils.deepClone(data));
		} else {
			return data[name];
		}
	}

	//设置数据对象值
	async setData(row, autoWrite = true) {
		this.#_data = {};
		if (!Array.isArray(this.entity.fields)) {
			throw new Error('entity fields format error');
		}
		let isWriteCreateData = false,
			isWriteUpdateData = false;

		await Promise.all(
			this.entity.fields.map(async (item) => {
				let { key, type, lang } = item;
				if (typeof row[key] != 'undefined') {
					let fieldValue = row[key];
					// 处理number类型
					if(type === 'number' && typeof row[key] === 'string') {
						fieldValue = Number(fieldValue);
						fieldValue = isNaN(fieldValue) ? 0 : fieldValue;
					}
					this.#_data[key] = fieldValue;
				} else if (this.autoWrite) {
					if (autoWrite) {
						switch (type) {
							case 'number':
								const value = item['default'] === void 0 ? 0 : Number(item['default']);
								this.#_data[key] = isNaN(value) ? 0 : value;
								break;
							case 'array':
								this.#_data[key] = item['default'] === void 0 ? [] : item['default'];
								break;
							case 'object':
								this.#_data[key] = item['default'] === void 0 ? {} : item['default'];
								break;
							case 'boolean':
								this.#_data[key] = item['default'] === void 0 ? false : item['default'];
								break;
							case 'string':
								this.#_data[key] = item['default'] === void 0 ? '' : item['default'];
								break;
							case 'any':
								this.#_data[key] = item['default'] === void 0 ? null : item['default'];
								break;
						}
					}
				}
				//重设属性值
				await this.setAttr(key, row[key]);
				if (typeof this.create_time === 'string' && this.create_time) {
					if (key === this.create_time) {
						isWriteCreateData = true;
					}
				}
				if (typeof this.update_time === 'string' && this.update_time) {
					if (key === this.update_time) {
						isWriteUpdateData = true;
					}
				}
			})
		);
		if (isWriteCreateData) {
			// 有值，赋值
			if (row[this.create_time]) {
				this.#_data[this.create_time] = row[this.create_time];
			}
			if (!this.#_data[this.create_time] && this.autoWriteTime && autoWrite) {
				this.#_data[this.create_time] = Date.now();
			}
		}
		if (isWriteUpdateData) {
			if (row[this.update_time]) {
				this.#_data[this.update_time] = row[this.update_time];
			}
			if (!this.#_data[this.update_time] && this.autoWriteTime && autoWrite) {
				this.#_data[this.update_time] = Date.now();
			}
		}
		return { ...this.#_data };
	}

	// 经过设置器的数据
	async getData(row) {
		this.#_origin = { ...row };
		let data = {};
		await Promise.all(
			Object.keys(row).map(async (key) => {
				data[key] = await this.getAttr(key, row);
			})
		);
		//追加属性
		if (this.$dx.utils.isArray(this.append)) {
			await Promise.all(
				this.append.map(async (item) => {
					let fn = this.#getAttrName('get_' + item + '_attr');
					if (typeof this[fn] == 'function') {
						data[item] = await this[fn](null, this.$dx.utils.deepClone(row));
					}
				})
			);
		}
		return data;
	}
	//获取原始值
	getOrigin() {
		return { ...this.#_origin };
	}
}
